using System;
using Symbonix.Library.DataStructure;
using System.Web.Security;
using Symbonix.Library.Web.Security.DAL.Repositories;
using System.Collections.Generic;
using Symbonix.Library.Web.Security.DAL.Entities;
using Symbonix.NorSoNet.Security.DAL.Repositories;
using Symbonix.NorSoNet.Security.DAL.Entities;
namespace Symbonix.NorSoNet.Security.BLL.Membership
{

    public class SystemUser : UserBase
    {

        private int id;
        public override int Id
        {
            get
            {
                return id;
            }
            set { id = value; }
        }

        private String userName;
        public override String UserName
        {
            get
            {
                return userName;
            }
            set { userName = value; }
        }

        private String email;
        public override String Email
        {
            get
            {
                return email;
            }
            set
            {
                email = value;
            }
        }

        private String firstName;
        public override String FirstName
        {
            get
            {
                return firstName;
            }
            set
            {
                firstName = value;
            }
        }

        private String lastName;
        public override String LastName
        {
            get
            {
                return lastName;
            }
            set
            {
                lastName = value;
            }
        }

        private String comment;
        public override String Comment
        {
            get
            {
                return comment;
            }
            set
            {
                comment = value;
            }
        }

        private bool isApproved;
        public override bool IsApproved
        {
            get
            {
                return isApproved;
            }
            set { isApproved = value; }
        }

        private bool isLockedOut;
        public override bool IsLockedOut
        {
            get
            {
                return isLockedOut;
            }
            set { isLockedOut = value; }
        }

        private DateTime creationDate;
        public override DateTime CreationDate
        {
            get
            {
                return creationDate;
            }
            set { creationDate = value; }
        }

        private DateTime lastLoginDate;
        public override DateTime LastLoginDate
        {
            get
            {
                return lastLoginDate;
            }
            set { lastLoginDate = value; }
        }

        private DateTime lastActivityDate;
        public override DateTime LastActivityDate
        {
            get
            {
                return lastActivityDate;
            }
            set { lastActivityDate = value; }
        }

        private DateTime lastPasswordChangedDate;
        public override DateTime LastPasswordChangedDate
        {
            get
            {
                return lastPasswordChangedDate;
            }
            set { lastPasswordChangedDate = value; }
        }

        private DateTime lastLockoutDate;
        public override DateTime LastLockoutDate
        {
            get
            {
                return lastLockoutDate;
            }
            set { lastLockoutDate = value; }
        }

        protected SystemUser() { }

        protected internal static IUser GetInstance() { return new SystemUser(); }

        /// <summary>
        /// Loads a generic user instance with the provided user id
        /// [Jalal]
        /// </summary>
        /// <param name="id">ID of the user for wich to return user instance</param>
        /// <returns>A generic user instance</returns>
        public override IUser Load(int id)
        {
            MembershipUser member = System.Web.Security.Membership.Provider.GetUser(id, false);
            if (member != null)
            {
                UserRepository userRepository = new UserRepository();
                User userData = userRepository.GetByPrimaryKey(Convert.ToInt32(member.ProviderUserKey));
                return LoadFromMembershipUser(member, userData.FirstName, userData.LastName);
            }
            return null;
        }

        /// <summary>
        /// Calls a specific user instance inside, so works as a 
        /// wrapper for specific user instance create method.
        /// [Jalal]
        /// </summary>
        /// <param name="userName">Unique username</param>
        /// <param name="password">User password</param>
        /// <param name="email">User email</param>
        /// <param name="firstName">User first name</param>
        /// <param name="lastName">User last name</param>
        /// <param name="role">User role to be applied</param>
        /// <param name="isApproved">User approve status to be applied</param>
        /// <param name="status">Membership create status for the create action as out parameter</param>
        /// <returns>Returns newly created specific user instance</returns>
        public override IUser Create(String userName, String password, String email, String firstName, String lastName,
            string role, bool isApproved, out MembershipCreateStatus status)
        {
            status = MembershipCreateStatus.ProviderError;
            IUser user = Symbonix.NorSoNet.Security.BLL.ModuleManager.MembershipFactory.GetUser(role);
            return user.Create(userName, password, email, firstName, lastName, role, isApproved, out status);
        }

        /// <summary>
        /// Calls a specific user instance inside, so works as a 
        /// wrapper for specific user instance create method.
        /// [Jalal]
        /// </summary>
        /// <param name="userName">Unique username of the user for wich to return user instance</param>
        /// <returns>A generic user instance</returns>
        public override IUser GetUserByUserName(String userName)
        {
            MembershipUser member = System.Web.Security.Membership.Provider.GetUser(userName, false);
            if (member != null)
            {
                UserRepository userRepository = new UserRepository();
                User userData = userRepository.GetByPrimaryKey(Convert.ToInt32(member.ProviderUserKey));
                return LoadFromMembershipUser(member, userData.FirstName, userData.LastName);
            }
            return null;
        }
        public override IUser GetUserByEmail(String email)
        {
            UserRepository userRepository = new UserRepository();
            User userData = userRepository.GetUserNameByEmail(email);
            return GetBizUserFromEntity(userData);
        }

        public override ReadWriteCustomCollection<IUser> FindUser(String searchString)
        {
            ReadWriteCustomCollection<IUser> userCollection = new ReadWriteCustomCollection<IUser>();
            int totalRecord = 0;
            MembershipUserCollection mucByName = System.Web.Security.Membership.Provider.FindUsersByName(searchString, 0, 100, out totalRecord);
            MembershipUserCollection mucByEmail = System.Web.Security.Membership.Provider.FindUsersByEmail(searchString, 0, 100, out totalRecord);

            System.Collections.Generic.List<int> ids = new List<int>();

            foreach (MembershipUser user in mucByName)
            {
                ids.Add(Int32.Parse(user.ProviderUserKey.ToString()));
            }
            foreach (MembershipUser user in mucByEmail)
            {
                int newId = Int32.Parse(user.ProviderUserKey.ToString());
                if (!IsIdExits(ids, newId))
                {
                    ids.Add(newId);
                }

            }
            ExtendedUserRepository eur = new ExtendedUserRepository();
            IList<User> users = eur.GetUsersById(ids);

            foreach (User user in users)
            {
                userCollection.Add(GetBizUserFromEntity(user));
            }

            return userCollection;

        }
        private IUser GetBizUserFromEntity(User user)
        {
            IUser bizUser = ModuleManager.MembershipFactory.GetUser();
            bizUser.UserName = user.UserName;
            bizUser.Id = user.UserID;
            bizUser.Email = user.Email;
            bizUser.FirstName = user.FirstName;
            bizUser.LastName = user.LastName;
            bizUser.Comment = user.Comment;
            bizUser.IsApproved = user.IsApproved;
            bizUser.IsLockedOut = user.IsLocked;
            bizUser.CreationDate = user.CreateDate;
            bizUser.LastLoginDate = user.LastLoginDate.Value;
            bizUser.LastActivityDate = user.LastActivityDate.Value;
            bizUser.LastPasswordChangedDate = user.LastPasswordChangeDate.Value;
            bizUser.LastLockoutDate = user.LastLockoutDate.Value;
            return bizUser;
        }

        private bool IsIdExits(List<int> ids, int newId)
        {
            foreach (int id in ids)
            {
                if (id == newId)
                    return true;
            }
            return false;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="oldPassword"></param>
        /// <param name="newPassword"></param>
        /// <returns></returns>
        public override bool ChangePassword(String oldPassword, String newPassword)
        {
            MembershipUser member = System.Web.Security.Membership.Provider.GetUser(UserName, false);
            return member.ChangePassword(oldPassword, newPassword);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="newPassword"></param>
        /// <returns></returns>
        public override bool ResetPassword(String userName, String newPassword)
        {
            MembershipUser member = System.Web.Security.Membership.Provider.GetUser(userName, false);
            string generatedPassword = member.ResetPassword();
            return member.ChangePassword(generatedPassword, newPassword);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="encryptedUserName"></param>
        /// <param name="userEmail"></param>
        /// <param name="newPassword"></param>
        /// <returns></returns>
        public override bool CreateNewPassword(Guid key, string userEmail, string newPassword)
        {
           ExtendedUserRepository eur = new ExtendedUserRepository();
            User user = eur.GetUserNameByEmail(userEmail);
            IUser newuser=this.Load(user.UserID);
            MembershipUser member = System.Web.Security.Membership.Provider.GetUser(user.UserName, false);

            VerificationCodeDataRepository varificationRepository = new VerificationCodeDataRepository();

            VerificationCodeData varificationData = varificationRepository.GetByGuiId(key);
           // string username = Symbonix.Library.Utility.Security.Decrypt(encryptedUserName, user.PasswordSalt, true);

            if (varificationData.ForUserID == user.UserID)
            {
                this.ResetPassword(user.UserName, newPassword);
                return true;
            }
            else
            {
                return false;
            }
        }
        public override bool ChangeEmail(String password, String newEmail)
        {
            try
            {
                MembershipUser member = System.Web.Security.Membership.Provider.GetUser(UserName, false);
                member.Email = newEmail;
                System.Web.Security.Membership.Provider.UpdateUser(member);
                return true;
            }
            catch
            {
                return false;
            }

        }

        public override bool UpdateUserFullName(string firstName, string lastName)
        {
            try
            {
                ExtendedUserRepository extendedRepository = new ExtendedUserRepository();
                User user = extendedRepository.GetUserByUserName(this.UserName);
                user.FirstName = firstName;
                user.LastName = lastName;
                extendedRepository.Update(user);
                return true;
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// Matches the username and password pair for a user to check
        /// whether the user account exists or not
        /// uses membership provider internally, so increaments 
        /// invalid password attemp on fail, and updates last login time 
        /// on success.
        /// [Jalal]
        /// </summary>
        /// <param name="username">username to check</param>
        /// <param name="password">password to match</param>
        /// <returns>true if the username/password pair is found, otherwise returns false</returns>
        public override bool ValidateUser(string username, string password)
        {
            return System.Web.Security.Membership.Provider.ValidateUser(username, password);
        }

        /// <summary>
        /// Creates a generic user instanace from a membership user
        /// [Jalal]
        /// </summary>
        /// <param name="member">membership user instance</param>
        /// <returns>Generic user instance</returns>
        protected IUser LoadFromMembershipUser(MembershipUser member, string firstName, string lastName)
        {
            if (member != null)
            {
                string[] roles = Roles.Provider.GetRolesForUser(member.UserName);
                if (roles != null && roles.Length > 0)
                {
                    IUser user = Symbonix.NorSoNet.Security.BLL.ModuleManager.MembershipFactory.GetUser(roles[0]);
                    if (user != null)
                    {
                        user.Id = Convert.ToInt32(member.ProviderUserKey);
                        user.Comment = member.Comment;
                        user.CreationDate = member.CreationDate;
                        user.Email = member.Email;
                        user.IsApproved = member.IsApproved;
                        user.IsLockedOut = member.IsLockedOut;
                        user.LastActivityDate = member.LastActivityDate;
                        user.LastLockoutDate = member.LastLockoutDate;
                        user.LastLoginDate = member.LastLoginDate;
                        user.LastPasswordChangedDate = member.LastPasswordChangedDate;

                        user.UserName = member.UserName;
                        user.FirstName = firstName;
                        user.LastName = lastName;
                        return user;
                    }
                }
                else
                {
                    SystemUser user = new SystemUser();
                    user.Id = Convert.ToInt32(member.ProviderUserKey);
                    user.Comment = member.Comment;
                    user.CreationDate = member.CreationDate;
                    user.Email = member.Email;
                    user.IsApproved = member.IsApproved;
                    user.IsLockedOut = member.IsLockedOut;
                    user.LastActivityDate = member.LastActivityDate;
                    user.LastLockoutDate = member.LastLockoutDate;
                    user.LastLoginDate = member.LastLoginDate;
                    user.LastPasswordChangedDate = member.LastPasswordChangedDate;
                    user.UserName = member.UserName;
                    user.FirstName = firstName;
                    user.LastName = lastName;
                    return user;
                }
            }
            return null;
        }

    }

}
